import numpy as np
from metrics import r2_score

class  LinearRegression3:
    def __init__(self):
        self.coef_=None #系数，θ1-θn
        self.interception_=None #截距，θ0
        self._theta=None #整体的θ列向量
    def fit_normal(self,x_train,y_train):#正规化方程
        assert x_train.shape[0]==y_train.shape[0]#x行数等于y的列数=>每个x都要有对应的y值
        #使1与众多参数合并成一个矩阵，便于与截距和参数的增广阵相乘[b,θ1,θ2....θn]
        x_b=np.hstack([np.ones((len(x_train),1)),x_train])
        """计算Θ矩阵"""
        self._theta=np.linalg.inv(x_b.T.dot(x_b)).dot(x_b.T).dot(y_train)
        """返回的参数矩阵形式是 [b,θ1,...θn]"""
        self.interception_=self._theta[0]#截距b
        self.coef_=self._theta[1:]#θ1-θn
        return self
    
    def predict(self,x_predict):
        assert self.coef_ is not None and self.interception_ is not None
        #保证输入数据集的列数（特征）等于特征个数
        assert x_predict.shape[1]==self.coef_.shape[0]
        #拼接
        X_b=np.hstack([np.ones((len(x_predict),1)),x_predict])
        return X_b.dot(self._theta)
    
    def score(self,x_test,y_test):
        y_predict=self.predict(x_test)
        return r2_score(y_test,y_predict)
    
    def __reper__(self):
        return "线性回归模型"